// 10.2 初识泛型算法
/**
 * 标准库提供了超过100个算法。幸运的是，与容器类似，这些算法有一致的结构。
 * 比起死记硬背全部100多个算法，理解此结构可以帮助我们更容易地学习和使用这些算法。
 * 除了少数例外，标准库算法都对一个范围内的元素进行操作。我们将此元素范围称为“输入范围”。
 * 接受输入范围的算法总是使用前两个参数来表示此范围，两个参数分别是指向要处理的第一个元素和尾元素之后位置的迭代器。
 */

#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array, std::stack, std::queue;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::begin, std::end, std::find, std::accumulate, std::equal;
using std::cin, std::cout, std::endl;

int main()
{
    // 10.2.1 只读算法
    vector<int> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int sum = accumulate(vec.cbegin(), vec.cend(), 0); // 对vec中的元素求和，和的初始值是0

    // 算法和元素类型
    vector<string> v = {"H", "e", "l", "l", "o"};
    string sum = accumulate(v.cbegin(), v.cend(), ""); // 错误，const char*上没有定义+运算符，原因在于我们传递了一个字符串字面值

    // 对于只读取而不改变元素的算法，通常最好使用cbegin（）和cend（）（参见9.2.3节，第298页）。
    // 但是，如果你计划使用算法返回的迭代器来改变元素的值，就需要使用begin（）和end（）的结果作为参数。

    // 操作两个序列的算法
    vector<string> roster1{"曾国藩", "张之洞", "杨度"};
    list<const char *> roster2{"李鸿章", "陈载礽", "张佩纶"};
    equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());
    // 由于equal利用迭代器完成操作，因此我们可以通过调用equal来比较两个不同类型的容器中的元素。
    // 而且，元素类型也不必一样，只要我们能用==来比较两个元素类型即可。

    // 那些只接受一个单一迭代器来表示第二个序列的算法，都假定第二个序列至少与第一个序列一样长。

    return 0;
}